home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip1292.zip / TAIL.C < prev    next >
C/C++ Source or Header  |  1992-12-26  |  5KB  |  196 lines

  1. /******************************************************************************
  2. TAIL.C  Display the last "n" lines of a file (5 lines by default).
  3. Written February 4, 1986 by Joe Huffman
  4. Modified October 5, 1986 by Joe Huffman
  5.   Utilize prototyping, fixed a bug, added (a few) comments and help.
  6.  
  7. Not copyrighted.
  8.  
  9. NOTE:  Compile using Datalight 'C' with flags "-mci".  Link with "_main.obj" to 
  10. get wildcard expansion of file names. 
  11.  
  12. Notice the use of "atoi ()" instead of sscanf () and the use of a local int to 
  13. ascii routine instead of printf () to save space in the final executable code.
  14. ******************************************************************************/ 
  15.  
  16. #include <stdio.h>
  17.  
  18. unsigned char head1[] = {"\n------- \""},
  19.               head2[] = {" -------\n"};
  20. FILE *fp;
  21. int filenum, cc;
  22. unsigned int linenum = 5, indx;
  23. long int *tail;
  24. void help (void);
  25.  
  26. main (argc, argv)
  27. int argc;
  28. unsigned char *argv[];
  29. {
  30.   if (argc <= 1)
  31.   {
  32.     help ();
  33.     exit (1);
  34.   }
  35.  
  36.   getlinenum (argc, argv);
  37.  
  38.   for (filenum = 1; filenum < argc; ++filenum)
  39.   {
  40.     if (*argv[filenum] == '/')
  41.       continue;
  42.     fp = fopen (argv[filenum], "rb");
  43.     if (!fp)
  44.     {
  45.       fputs (head1, stderr);
  46.       fputs (argv[filenum], stderr);
  47.       fputs ("\" not found.", stderr);
  48.       fputs (head2, stderr);
  49.     }
  50.     else
  51.     {
  52.       fputs (head1, stdout);
  53.       fputs (argv[filenum], stdout);
  54.       gettail ();
  55.       fputs (head2, stdout);
  56.       for (cc = getc (fp); cc != EOF; cc = getc (fp))
  57.         fputc (cc, stdout);
  58.       fclose (fp);
  59.     }
  60.   }
  61. }
  62. /******************************************************************************
  63. Get the number of lines to display at the "tail" of each file from the command 
  64. line.
  65. ******************************************************************************/
  66. getlinenum (n, str)
  67. int n;
  68. unsigned char *str[];
  69. {
  70.   int atoi (char *);
  71.  
  72.   for (--n; n; --n)
  73.   {
  74.     ++str;
  75.     if (**str == '/')
  76.     {
  77.       linenum = atoi (*(str) + 1);
  78.       if (linenum <= 0)
  79.         linenum = 5;
  80.     }
  81.   }
  82.   linenum++;  /* Because we save a pointer to the end of the PREVIOUS line. */
  83. }
  84. /******************************************************************************
  85. Set the file pointer "fp" to "linenum - 1" lines before the end of the file.
  86. ******************************************************************************/
  87. gettail ()
  88. {
  89.   unsigned char outstr[15];
  90.   void *malloc (unsigned int);
  91.   unsigned long int currline = 0L;
  92.  
  93.   tail = (long int *)malloc (sizeof(*tail) * linenum);
  94.   if (!tail)
  95.   {
  96.     fputs ("Insufficient memory.", stderr);
  97.     exit (1);
  98.   }
  99.   tail[0] = ftell (fp);
  100.   indx = 0;
  101.  
  102.   for (cc = getc (fp); cc != EOF; cc = getc (fp))
  103.   {
  104.     if (cc == '\r')
  105.     {
  106.       ++currline;
  107.       cc = getc (fp);
  108.       if (cc != '\n')
  109.         ungetc (cc, fp);
  110.       ++indx;
  111.       indx %= linenum;
  112.       tail[indx] = ftell (fp);
  113.     }
  114.     else
  115.     {
  116.       if (cc == '\n')
  117.       {
  118.         ++currline;
  119.         cc = getc (fp);
  120.         if (cc != '\r')
  121.           ungetc (cc, fp);
  122.         ++indx;
  123.         indx %= linenum;
  124.         tail[indx] = ftell (fp);
  125.       }
  126.     }
  127.   }
  128.   fputs ("\" ", stdout);
  129.   ltoa (currline, outstr);
  130.   fputs (outstr, stdout);
  131.   fputs (" lines", stdout);
  132.   if (currline >= linenum - 1)
  133.   {
  134.     indx++;
  135.     indx %= linenum;
  136.   }
  137.   else
  138.     indx = 0;
  139.   
  140.   if (fseek (fp, tail[indx], 0) == -1)
  141.   {
  142.     fputs ("\nFile seek error.", stderr);
  143.     exit (1);
  144.   }
  145.   free (tail);
  146. }
  147. /******************************************************************************
  148. long integer to ASCII.  Use this function rather than function in the library 
  149. to save many bytes in the ".COM" file.
  150. ******************************************************************************/
  151. ltoa (val, cp)
  152. long int val;     /* the number to convert */
  153. unsigned char *cp;    /* the address of the string */
  154. {
  155.   unsigned char tempc[15], *tcptr;
  156.   int sign;
  157.   static unsigned char dig[] = {"0123456789"};
  158.  
  159.   if (val < 0)
  160.   {
  161.     val = -val;
  162.     sign = 1;
  163.   }
  164.   else
  165.     sign = 0;
  166.  
  167.   *(tcptr = tempc + 11) = '\0';
  168.   do 
  169.   {
  170.     *--tcptr = dig[(int)(val % 10)];
  171.   }while (val /= 10);
  172.   if (sign)
  173.     *--tcptr = '-';
  174.   strcpy (cp, tcptr);
  175. }
  176. /******************************************************************************
  177. Tell the user what the program is and how to use it.
  178. ******************************************************************************/
  179. void help ()
  180. {
  181.   char *ptr;
  182.   static char help_str[] = 
  183.   { "\
  184. Command error: No file(s) specified.\n\
  185. Written by Joe Huffman.\n\
  186. TAIL is a program that prints out only the last lines of a program.\n\
  187. usage:\n\
  188.        TAIL filename [filename] [/n]\n\n\
  189.             filename - The name of a valid file, wildcards accepted.\n\
  190.             n - number of lines to print out, 5 by default."
  191.   };
  192.  
  193.   for (ptr = &help_str[0]; *ptr; ptr++)
  194.     fputc (*ptr, stdout);
  195. }
  196.